/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 文件名：	BShareUserAgent.java
 * 模块说明：	
 * 修改历史：
 * Nov 12, 2007 - guzhidi - 创建。
 */
package com.hd123.rumba.user.biz.share;

import java.util.ArrayList;
import java.util.List;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.type.Type;

import com.hd123.rumba.domain.CDomain;
import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.organization.IOrganization;
import com.hd123.rumba.organization.IOrganizationMgr;
import com.hd123.rumba.organization.biz.IBOrganizationMgr;
import com.hd123.rumba.organization.biz.SOrganization;
import com.hd123.rumba.runtime.IVersionedPersistent;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.user.CRole;
import com.hd123.rumba.user.IRole;
import com.hd123.rumba.user.IRoleDomain;
import com.hd123.rumba.user.IRoleMgr;
import com.hd123.rumba.user.IUserRole;
import com.hd123.rumba.user.biz.IBRoleMgr;
import com.hd123.rumba.user.biz.IBUserMgr;
import com.hd123.rumba.user.biz.SUser;
import com.hd123.rumba.util.ClassifiedHashtable;

/**
 * @author guzhidi
 * 
 */
public class BRoleMemberAgent implements IBRoleMemberAgent {

  /** role的uuid */
  protected String roleUuid = null;

  @SuppressWarnings("unchecked")
  public void executeCommandsT(List<BRoleMemberCommand> cmds, OperateContext operate, long oca)
      throws BusinessException, HibernateException {
    checkIn();
    IRole prole = getRoleMgr().getRole(roleUuid);
    IBUserMgr userMgr = (IBUserMgr) NamingMgr.getInstance().lookupMgr(IBUserMgr.class);
    IBRoleMgr roleMgr = (IBRoleMgr) NamingMgr.getInstance().lookupMgr(IBRoleMgr.class);
    ClassifiedHashtable h = checkOca(prole, oca, CRole.CAPTION_CLASS, prole.getNameCode());
    if (h != null)
      throw new BusinessException(h.getAllMessages());

    List oldUsers = getSession().find(
        "select o.user.uuid from " + IUserRole.class.getName() + " o where o.role.uuid = ?",
        roleUuid, Hibernate.STRING);
    // 进行命令的操作
    List<String> newUsers = new ArrayList<String>();
    newUsers.addAll(oldUsers);
    for (int i = 0; i < cmds.size(); i++) {
      BRoleMemberCommand cmd = cmds.get(i);
      if (BRoleMemberCommand.VALUE_COMMAND_CHECK.equals(cmd.getCommand())) {
        if (!newUsers.contains(cmd.getUserUuid()))
          newUsers.add(cmd.getUserUuid());
      } else if (BRoleMemberCommand.VALUE_COMMAND_UNCHECK.equals(cmd.getCommand())) {
        if (newUsers.contains(cmd.getUserUuid()))
          newUsers.remove(cmd.getUserUuid());
      }
    }
    List<SUser> users = new ArrayList<SUser>();
    for (int i = 0; i < newUsers.size(); i++) {
      SUser user = (SUser) userMgr.getUser(newUsers.get(i), SUser.class);
      if (user != null)
        users.add(user);
    }

    Transaction tx = getSession().beginTransaction();
    try {
      roleMgr.saveRoleUsersT(roleUuid, users, operate, oca);
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      throw new BusinessException(e);
    }
  }

  public List<BRoleMemberAssign> getLowerMemberAssigns(String domainUuid) throws BusinessException,
      HibernateException {
    checkIn();
    List<BRoleMemberAssign> bsuas = new ArrayList<BRoleMemberAssign>();
    IOrganizationMgr orgMgr = (IOrganizationMgr) NamingMgr.getInstance().lookupMgr(
        IOrganizationMgr.class);
    IOrganization org = orgMgr.getOrganizationByOrgDomain(domainUuid);
    List subOrgs = orgMgr.getLowerOrganizations(org);
    for (int i = 0; i < subOrgs.size(); i++) {
      IOrganization subOrg = (IOrganization) subOrgs.get(i);
      bsuas.add(getMemberAssign(subOrg.getOrganizationDomain().getUuid()));
    }
    return bsuas;
  }

  @SuppressWarnings("unchecked")
  private void getAllUserCount(String domainUuid, List list) throws HibernateException,
      BusinessException {
    list.add(getUserCount(domainUuid));
    IDomain domain = getDomainMgr().getDomain(domainUuid);
    List<IDomain> childrenDomains = getDomainMgr().getDomainsByParent(domain);
    for (int i = 0; i < childrenDomains.size(); i++) {
      getAllUserCount(childrenDomains.get(i).getUuid(), list);
    }
  }

  public BRoleMemberAssign getMemberAssign(String domainUuid) throws BusinessException,
      HibernateException {
    checkIn();
    BRoleMemberAssign sa = new BRoleMemberAssign();
    IBOrganizationMgr orgMgr = (IBOrganizationMgr) NamingMgr.getInstance().lookupMgr(
        IBOrganizationMgr.class);
    SOrganization org = (SOrganization) orgMgr.getOrganizationByOrgDomain(domainUuid,
        SOrganization.class);
    sa.setOrganization(org);
    sa.setDomainUuid(domainUuid);
    sa.setUserCount(this.getUserCount(domainUuid));
    sa.setChildrenCheckedCount(getChildrenCheckedCount(domainUuid));
    List list = new ArrayList();
    getAllUserCount(domainUuid, list);
    int count = 0;
    for (Object o : list) {
      Integer i = (Integer) o;
      count += i.intValue();
    }
    sa.setAllUsersCount(Integer.valueOf(count));
    sa.setChecked(getChecked(domainUuid));
    return sa;
  }

  private boolean getChecked(String domainUuid) throws HibernateException, BusinessException {
    List list = getSession().find(
        "select rs from " + IRoleDomain.class.getName()
            + " rs where rs.role.uuid = ? and rs.domain.uuid = ?", new Object[] {
            getRoleUuid(), domainUuid }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
    if (list.size() > 0)
      return true;
    else
      return false;
  }

  private Integer getUserCount(String domainUuid) throws HibernateException, BusinessException {
    List list = getSession().find(
        "select count(o) from " + IUserRole.class.getName()
            + " o where o.role.uuid = ? and o.user.domain.uuid = ?", new Object[] {
            roleUuid, domainUuid }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
    if (list.size() > 0)
      return (Integer) list.get(0);
    else
      return new Integer(0);
  }

  private Integer getChildrenCheckedCount(String domainUuid) throws HibernateException,
      BusinessException {
    List<Integer> list = new ArrayList<Integer>();
    getLowerChildrenCheckedCount(list, domainUuid);
    int counts = 0;
    for (Integer count : list) {
      counts += count.intValue();
    }
    return Integer.valueOf(counts);
  }

  private void getLowerChildrenCheckedCount(List<Integer> list, String domainUuid)
      throws HibernateException, BusinessException {
    List countList = getSession()
        .find(
            "select count(d) from "
                + IDomain.class.getName()
                + " d, "
                + IRoleDomain.class.getName()
                + " rd where d.state != ? and d.upperDomain.uuid = ? and d.uuid = rd.domain.uuid and rd.role.uuid = ?",
            new Object[] {
                CDomain.VALUE_STATE_DELETED, domainUuid, getRoleUuid() }, new Type[] {
                Hibernate.INTEGER, Hibernate.STRING, Hibernate.STRING });

    if (countList.size() > 0)
      list.add((Integer) countList.get(0));

    IOrganizationMgr orgMgr = (IOrganizationMgr) NamingMgr.getInstance().lookupMgr(
        IOrganizationMgr.class);
    IOrganization org = orgMgr.getOrganizationByOrgDomain(domainUuid);
    List subOrgs = orgMgr.getLowerOrganizations(org);
    for (int i = 0; i < subOrgs.size(); i++) {
      IOrganization subOrg = (IOrganization) subOrgs.get(i);
      getLowerChildrenCheckedCount(list, subOrg.getOrganizationDomain().getUuid());
    }
  }

  protected ClassifiedHashtable checkOca(IVersionedPersistent entity, long oca,
      String classCaption, String entitySpec) throws BusinessException {
    if (entity.getUuid() != null && entity.getOca() != oca) {
      ClassifiedHashtable h = new ClassifiedHashtable();
      h.putMessage("oca", ClassifiedHashtable.ERROR, "指定" + classCaption + "[" + entitySpec
          + "]已经被其他用户修改，操作将被取消。");
      return h;
    } else
      return null;
  }

  protected Session getSession() throws BusinessException, HibernateException {
    return getDomainMgr().getSession();
  }

  private IDomainMgr domainMgr = null;

  private IDomainMgr getDomainMgr() throws BusinessException {
    if (domainMgr == null)
      domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    return domainMgr;
  }

  private IRoleMgr roleMgr = null;

  private IRoleMgr getRoleMgr() throws BusinessException {
    if (roleMgr == null)
      roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    return roleMgr;
  }

  protected void checkIn() throws BusinessException, HibernateException {
    if (roleUuid == null)
      throw new BusinessException("指定属性roleUuid不可为空。");
  }

  public void setRoleUuid(String roleUuid) throws BusinessException {
    this.roleUuid = roleUuid;
  }

  public String getRoleUuid() throws BusinessException {
    return this.roleUuid;
  }
}
